#include "app_mqtt.h"
#include "log/log.h"
#include <MQTTClient.h>
#include <string.h>

static MQTTClient_message pubmsg = MQTTClient_message_initializer; // 消息对象
static MQTTClient client; // 客户端
static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; // 连接配置
static int (*recv_callback)(char *json) = NULL; // 当收到远程消息时的调用它

// 发送消息完成的回调
void delivered(void *context, MQTTClient_deliveryToken dt)
{
    printf("发送消息完成 \n");
}
// 收到远程消息的回调
// 注意： 返回1代表成功，0代表失败
int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int result = 0;
    // 如果有处理远程消息的回调函数，则调用它
    if (recv_callback != NULL)
    {
        result = recv_callback(message->payload)==0 ? 1 : 0;
    }
    
    // 释放内存
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    
    // 返回结果
    return result;
}
// 连接断开的回调
void connlost(void *context, char *cause)
{
    printf("连接断开，原因：%s", cause);
}

/**
 * 初始化MQTT客户端
 */
int app_mqtt_init()
{
    // 创建MQTT客户端
    if (MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)!=0)
    {
        log_error("创建MQTT客户端失败!");
        return -1;
    }
    // 注册回调函数
    if (MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered) != 0)
    {
        log_error("注册回调函数失败!");
        MQTTClient_destroy(&client);
        return -1;
    }

    // 连接MQTT服务器
    if (MQTTClient_connect(client, &conn_opts) != 0)
    {
        log_error("连接MQTT服务器失败!");
        MQTTClient_destroy(&client);
        return -1;
    }

    // 订阅主题
    if (MQTTClient_subscribe(client, TOPIC_RTG, QOS) != 0)
    {
        log_error("订阅主题失败!");
        app_mqtt_close();
        return -1;
    }

    log_debug("MQTT客户端初始化成功!");
    
    return 0;
}

/**
 * 关闭MQTT客户端
 */
void app_mqtt_close()
{
    MQTTClient_disconnect(client, TIMEOUT);
    MQTTClient_destroy(&client);
}

/**
 * 发布消息
 */
int app_mqtt_send(char *json)
{
    pubmsg.payload = json;
    pubmsg.payloadlen = strlen(json);
    pubmsg.qos = QOS;
    int result = MQTTClient_publishMessage(client, TOPIC_GTR, &pubmsg, NULL);
    if (result != 0)
    {
        log_error("发布消息失败!");
        return -1;
    }
    return 0;
}

/**
 * 注册接收处理远程消息的回调
 */
void app_mqtt_registerRecvCallback(int (*callback)(char *json))
{
    recv_callback = callback;
}